package com.loan.web.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.loan.common.core.domain.AjaxResult;
import com.loan.common.pdf.PDFUtil;
import com.loan.common.utils.DateUtils;
import com.loan.common.utils.StringUtils;
import com.loan.system.create.domain.AssistPdfBaseConf;
import com.loan.system.create.domain.AssistPdfContentConf;
import com.loan.system.create.domain.AssistPdfCreateFile;
import com.loan.system.create.domain.AssistPdfTableConf;
import com.loan.system.create.service.IAssistPdfBaseConfService;
import com.loan.system.create.service.IAssistPdfContentConfService;
import com.loan.system.create.service.IAssistPdfCreateFileService;
import com.loan.system.create.service.IAssistPdfTableConfService;
import com.loan.system.domain.work.domain.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

import static com.loan.common.pdf.PDFUtil.getRandomValue;

/**
 * packageName com.loan.web.utils
 *
 * @author Sophia
 * @className ExportBankUtil
 * @description TODO
 * @date 2024/12/11
 */
@Slf4j
@Component
public class ExportBankUtil {

    @Autowired
    private IAssistPdfBaseConfService assistPdfBaseConfService;
    @Autowired
    private IAssistPdfContentConfService assistPdfContentConfService;
    @Autowired
    private IAssistPdfTableConfService assistPdfTableConfService;
    @Autowired
    private IAssistPdfCreateFileService assistPdfCreateFileService;

    /**
     * 创建NH的PDF文件(旧版)
     *
     * @param pdfReq 入参
     * @return
     * @throws Exception
     */
    public AjaxResult createNhPdfTemp(CreatePdfReq pdfReq) throws Exception {
        AssistPdfCreateFile assistPdfCreateFile = null;
        if (pdfReq.getCreateFileId() == null) {
            assistPdfCreateFile = new AssistPdfCreateFile();
        } else {
            assistPdfCreateFile = assistPdfCreateFileService.selectAssistPdfCreateFileById(pdfReq.getCreateFileId());
        }
        // 设置值
        assistPdfCreateFile.setNhDataByReq(pdfReq);
        log.info("检验收支数据是否有效...");
        List<TableValue> inValueList = pdfReq.getInValueList();
        List<TableValue> outValueList = pdfReq.getOutValueList();
        if (!(inValueList != null && inValueList.size() > 0)) {
            log.info("收入明细数据无效，请检查!");
            return AjaxResult.error("收入明细数据无效，请检查");
        }
        if (!(outValueList != null && outValueList.size() > 0)) {
            log.info("支出明细数据无效，请检查!");
            return AjaxResult.error("支出明细数据无效，请检查");
        }
        log.info("合并支出并按照时间日期排序...");
        List<TableValue> needSortDataList = new ArrayList<>();
        needSortDataList.addAll(inValueList);
        needSortDataList.addAll(outValueList);
        List<TableValue> sortedDataList = needSortDataList.stream().sorted(Comparator.comparingInt(TableValue::getSortNo)).collect(Collectors.toList());
        // 处理修改后的值
        Integer money = pdfReq.getOriginalMoney();
        for (TableValue value : sortedDataList) {
            String moneyStr = value.getTransactionMoney();
            Integer tranMoney = value.getTransactionMoneyInt();
            boolean addFlag = StringUtils.contains(moneyStr, "+");
            if (addFlag) {
                money += tranMoney;
                moneyStr = "+" + tranMoney;
            } else {
                Integer tempMoney = money;
                Integer orginMoney = tranMoney;
                money += orginMoney;
                moneyStr = String.valueOf(tranMoney);
                while (money <= 0) {
                    orginMoney = orginMoney / 2;
                    money = tempMoney - orginMoney;
                    moneyStr = "-" + orginMoney;
                }
            }
            value.setTransactionMoney(moneyStr + ".00");
            value.setCurrentBalance(String.valueOf(money) + ".00");
        }

        // 生成的PDF文件地址
        log.info("参数以处理完成，开始生成PDF文件信息...");
        OutputStream outputStream = null;
        try {
            // 定义全局的字体静态变量
            BaseFont bf;
            Font font = null;
            Font cellContentFont = null;
            AssistPdfBaseConf baseConf = assistPdfBaseConfService.selectAssistPdfBaseConfById(pdfReq.getTypeId());
            String pdfBaseSavePath = baseConf.getPdfBaseSavePath();
            // 随机生成账号
            String accountNo = (getRandomValue() + getRandomValue()).substring(1);
            assistPdfCreateFile.setAccountNo(accountNo);
            assistPdfCreateFile.setPdfFileName();
            assistPdfCreateFile.setPdfFilePath(pdfBaseSavePath);

            File file = new File(assistPdfCreateFile.getPdfFilePath());
            outputStream = new FileOutputStream(file);

            String fontPath = baseConf.getPdfBaseFontPath();
            // 最大宽度
            //创建字体
            bf = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            //使用字体并给出颜色
            font = new Font(bf, baseConf.getPdfBaseTitleFontSize(), Integer.valueOf(baseConf.getPdfBaseTitleFontStyle()), BaseColor.BLACK);
            // 不同字体（这里定义为同一种字体：包含不同字号、不同style）
            BaseFont bfChinese = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            cellContentFont = new Font(bfChinese, baseConf.getPdfBaseGlobalFontSize(), Integer.valueOf(baseConf.getPdfBaseGlobalFontStyle()));

            // 设置PDF大小
            Document document = new Document(new RectangleReadOnly(Float.valueOf(baseConf.getPdfPaperWidth()), Float.valueOf(baseConf.getPdfPaperHeight()))); // A4纸张
            //设置页边距  60:左边距，60：右边距，72：上边距，72：下边距
            document.setMargins(baseConf.getPdfPaperLeftMargin(), baseConf.getPdfPaperRightMargin(), baseConf.getPdfPaperTopMargin(), baseConf.getPdfPaperBottomMargin());
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            //添加页码
            // writer.setPageEvent(new PdfPageUtil());
            //打开生成的pdf文件
            document.open();
            //设置内容
            Paragraph paragraph = new Paragraph(baseConf.getPdfBaseTitle(), font);
            paragraph.setAlignment(Integer.valueOf(baseConf.getPdfBaseTitleAlign())); // 居中显示
            //引用内容
            document.add(paragraph);

            PdfPTable tb = new PdfPTable(Math.toIntExact(baseConf.getPdfBaseDescNum()));
            tb.setWidthPercentage(100);

            // 查询描述内容配置信息
            log.info("查询描述文件配置信息...");
            AssistPdfContentConf contCont = new AssistPdfContentConf();
            contCont.setBaseConfId(baseConf.getId());
            List<AssistPdfContentConf> contentList = assistPdfContentConfService.selectAssistPdfContentConfList(contCont);
            List<AssistPdfContentConf> contentSortList = contentList.stream().sorted(Comparator.comparingInt(AssistPdfContentConf::getPdfContentSort)).collect(Collectors.toList());
            if (contentSortList != null && contentSortList.size() > 0) {
                for (AssistPdfContentConf contentConf : contentSortList) {
                    String pdfContentTitle = contentConf.getPdfContentTitle();
                    if (pdfContentTitle.contains("{userName}")) {
                        pdfContentTitle = pdfContentTitle.replace("{userName}", pdfReq.getUserName());
                    }
                    if (pdfContentTitle.contains("{accountNo}")) {
                        if (StringUtils.isBlank(pdfReq.getAccountNo())) {
                            pdfContentTitle = pdfContentTitle.replace("{accountNo}", accountNo);
                        } else {
                            pdfContentTitle = pdfContentTitle.replace("{accountNo}", pdfReq.getAccountNo());
                        }
                    }
                    if (pdfContentTitle.contains("{serialNo}")) {
                        if (StringUtils.isBlank(pdfReq.getSerialNo())) {
                            // 为空，则随机生成
                            String time = pdfReq.getEndTime().replace("-", "");
                            time = time.substring(2) + new SimpleDateFormat("HHmmss").format(new Date());
                            time = time + getRandomValue().substring(2);
                            pdfContentTitle = pdfContentTitle.replace("{serialNo}", time);
                            assistPdfCreateFile.setSerialNo(time);
                        } else {
                            pdfContentTitle = pdfContentTitle.replace("{serialNo}", pdfReq.getSerialNo());
                        }
                    }
                    if (pdfContentTitle.contains("{startTime}")) {
                        pdfContentTitle = pdfContentTitle.replace("{startTime}", pdfReq.getStartTime().replace("-", ""));
                    }
                    if (pdfContentTitle.contains("{endTime}")) {
                        pdfContentTitle = pdfContentTitle.replace("{endTime}", pdfReq.getEndTime().replace("-", ""));
                    }
                    PDFUtil.getCellValue(tb, pdfContentTitle, cellContentFont, null, Integer.parseInt(contentConf.getPdfContentAlign()));
                }
                document.add(tb);
            }

            log.info("添加图片logo到PDF文件中...");
            // 添加图片到PDF文件中
            PDFUtil.addImg(document, baseConf.getPdfBaseImagePath(), 50f, 50f, 460f, 710f);

            AssistPdfTableConf tableConf = new AssistPdfTableConf();
            tableConf.setBaseConfId(baseConf.getId());
            List<AssistPdfTableConf> tableList = assistPdfTableConfService.selectAssistPdfTableConfList(tableConf);
            List<AssistPdfTableConf> tableSortList = tableList.stream().sorted(Comparator.comparingInt(AssistPdfTableConf::getPdfTableSort)).collect(Collectors.toList());
            if (tableSortList != null && tableSortList.size() > 0) {
                log.info("查询配置信息，并生成PDF内容...");
                float[] width = new float[tableSortList.size()];
                for (int i = 0; i < tableSortList.size(); i++) {
                    width[i] = Float.valueOf(tableSortList.get(i).getPdfTableCellWidth());
                }
                PdfPTable table1 = new PdfPTable(width);
                table1.setSpacingBefore(4f);
                // 设置表格宽度为100%
                table1.setWidthPercentage(100.0F);
                table1.getDefaultCell().setHorizontalAlignment(1);
                // 设置表格上边框
                log.info("设置表格表头上边框信息...");
                for (int i = 0; i < tableSortList.size(); i++) {
                    PdfPCell cell = new PdfPCell(new Paragraph("", font));
                    cell.setFixedHeight(1); // 设置高度
                    cell.setHorizontalAlignment(0); // 设置对齐方式 默认水平左对齐
                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
                    cell.disableBorderSide(13); // 设置边框信息 默认只显示上下
                    table1.addCell(cell);
                }
                document.add(table1);

                PdfPTable table3 = new PdfPTable(width);
                table3.setSpacingBefore(0f);
                // 设置表格宽度为100%
                table3.setWidthPercentage(100.0F);
                table3.setHeaderRows(1);
                table3.getDefaultCell().setHorizontalAlignment(1);
                log.info("设置表格表头标题信息...");
                for (AssistPdfTableConf tc : tableSortList) {
                    PDFUtil.getCellTitleValue(table3, tc.getPdfTableTitle(), cellContentFont, Integer.parseInt(tc.getPdfTableTitleAlign()), 15);
                }
                // 设置表格表头下边框
                log.info("设置表格表头下边框信息...");
                for (int i = 0; i < tableSortList.size(); i++) {
                    PdfPCell cell = new PdfPCell(new Paragraph("", font));
                    cell.setFixedHeight(1); // 设置高度
                    cell.setHorizontalAlignment(0); // 设置对齐方式 默认水平左对齐
                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
                    cell.disableBorderSide(14); // 设置边框信息 默认只显示上下
                    table3.addCell(cell);
                }

                // 随机生成表格内容数据
                log.info("随机抓取生成数据到PDF表格中...");
                int flag = 0;
                List<String> fieldValueList = this.getFieldValue(sortedDataList);
                for (String value : fieldValueList) {
                    PDFUtil.getCellValue(table3, value, cellContentFont, Integer.parseInt(tableSortList.get(flag).getPdfTableValueBorderConf()),
                            Integer.parseInt(tableSortList.get(flag).getPdfTableValueAlign()));
                    if ((flag + 1) == tableSortList.size()) {
                        // 大小相同时，则置0
                        flag = 0;
                    } else {
                        flag++;
                    }
                }
                document.add(table3);
                log.info("PDF文件生成完成...");
            }
            //关闭文档
            document.close();
            // 信息入库操作
            if (assistPdfCreateFile.getId() == null) {
                assistPdfCreateFileService.insertAssistPdfCreateFile(assistPdfCreateFile);
            } else {
                assistPdfCreateFileService.updateAssistPdfCreateFile(assistPdfCreateFile);
            }
        } catch (DocumentException e) {
            log.error("生成PDF文件失败: {}", e.getMessage());
            log.error(e.getMessage(), e);
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
        return AjaxResult.success();
    }

    /**
     * 创建NH的PDF文件
     *
     * @param nhVo 入参
     * @return
     * @throws Exception
     */
    public AjaxResult createNhPdf(NhVo nhVo) throws Exception {
        AssistPdfCreateFile assistPdfCreateFile = null;
        if (nhVo.getCreateFileId() == null) {
            assistPdfCreateFile = new AssistPdfCreateFile();
        } else {
            assistPdfCreateFile = assistPdfCreateFileService.selectAssistPdfCreateFileById(nhVo.getCreateFileId());
        }
        // 设置值
        // 随机生成账号
        if (StringUtils.isBlank(nhVo.getAccountNo())) {
            String accountNo = (getRandomValue() + getRandomValue()).substring(1);
            nhVo.setAccountNo(accountNo);
        }
        assistPdfCreateFile.setAccountNo(nhVo.getAccountNo());
        assistPdfCreateFile.setPdfFileName();
        assistPdfCreateFile.setNhDataByReq(nhVo);

        log.info("设置每一行每一列的值...");
        List<String> valueList = new ArrayList<>();
        List<NhPdfDomain> sortedDataList = nhVo.getSortDataList();
        for (NhPdfDomain domain : sortedDataList) {
            valueList.add(domain.getTransactionDate());
            valueList.add(domain.getTransactionTime());
            valueList.add(domain.getTransactionSummary());
            valueList.add(domain.getDealAmount());
            valueList.add(domain.getCurrentBalance());
            valueList.add(domain.getOppositionInformation());
            valueList.add(domain.getLogNo());
            valueList.add(domain.getTransactionChannels());
            valueList.add(domain.getTransactionNote());
        }

        // 生成的PDF文件地址
        log.info("参数以处理完成，开始生成PDF文件信息...");
        OutputStream outputStream = null;
        try {
            // 定义全局的字体静态变量
            BaseFont bf;
            Font font = null;
            Font cellContentFont = null;
            AssistPdfBaseConf baseConf = assistPdfBaseConfService.selectAssistPdfBaseConfById(nhVo.getTypeId());
            String pdfBaseSavePath = baseConf.getPdfBaseSavePath();

            assistPdfCreateFile.setPdfFilePath(pdfBaseSavePath);

            File file = new File(assistPdfCreateFile.getPdfFilePath());
            outputStream = new FileOutputStream(file);

            String fontPath = baseConf.getPdfBaseFontPath();
            // 最大宽度
            //创建字体
            bf = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            //使用字体并给出颜色
            font = new Font(bf, baseConf.getPdfBaseTitleFontSize(), Integer.valueOf(baseConf.getPdfBaseTitleFontStyle()), BaseColor.BLACK);
            // 不同字体（这里定义为同一种字体：包含不同字号、不同style）
            BaseFont bfChinese = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            cellContentFont = new Font(bfChinese, baseConf.getPdfBaseGlobalFontSize(), Integer.valueOf(baseConf.getPdfBaseGlobalFontStyle()));

            // 设置PDF大小
            Document document = new Document(new RectangleReadOnly(Float.valueOf(baseConf.getPdfPaperWidth()), Float.valueOf(baseConf.getPdfPaperHeight()))); // A4纸张
            //设置页边距  60:左边距，60：右边距，72：上边距，72：下边距
            document.setMargins(baseConf.getPdfPaperLeftMargin(), baseConf.getPdfPaperRightMargin(), baseConf.getPdfPaperTopMargin(), baseConf.getPdfPaperBottomMargin());
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            //添加页码
            // writer.setPageEvent(new PdfPageUtil());
            //打开生成的pdf文件
            document.open();
            //设置内容
            Paragraph paragraph = new Paragraph(baseConf.getPdfBaseTitle(), font);
            paragraph.setAlignment(Integer.valueOf(baseConf.getPdfBaseTitleAlign())); // 居中显示
            //引用内容
            document.add(paragraph);

            PdfPTable tb = new PdfPTable(Math.toIntExact(baseConf.getPdfBaseDescNum()));
            tb.setWidthPercentage(100);

            // 查询描述内容配置信息
            log.info("查询描述文件配置信息...");
            AssistPdfContentConf contCont = new AssistPdfContentConf();
            contCont.setBaseConfId(baseConf.getId());
            List<AssistPdfContentConf> contentList = assistPdfContentConfService.selectAssistPdfContentConfList(contCont);
            List<AssistPdfContentConf> contentSortList = contentList.stream().sorted(Comparator.comparingInt(AssistPdfContentConf::getPdfContentSort)).collect(Collectors.toList());
            if (contentSortList != null && contentSortList.size() > 0) {
                for (AssistPdfContentConf contentConf : contentSortList) {
                    String pdfContentTitle = contentConf.getPdfContentTitle();
                    if (pdfContentTitle.contains("{userName}")) {
                        pdfContentTitle = pdfContentTitle.replace("{userName}", nhVo.getUserName());
                    }
                    if (pdfContentTitle.contains("{accountNo}")) {
                        pdfContentTitle = pdfContentTitle.replace("{accountNo}", nhVo.getAccountNo());
                    }
                    if (pdfContentTitle.contains("{serialNo}")) {
                        if (StringUtils.isBlank(nhVo.getSerialNo())) {
                            // 为空，则随机生成
                            String time = nhVo.getEndTime().replace("-", "");
                            time = time.substring(2) + new SimpleDateFormat("HHmmss").format(new Date());
                            time = time + getRandomValue().substring(2);
                            pdfContentTitle = pdfContentTitle.replace("{serialNo}", time);
                            assistPdfCreateFile.setSerialNo(time);
                        } else {
                            pdfContentTitle = pdfContentTitle.replace("{serialNo}", nhVo.getSerialNo());
                        }
                    }
                    if (pdfContentTitle.contains("{startTime}")) {
                        pdfContentTitle = pdfContentTitle.replace("{startTime}", nhVo.getStartTime().replace("-", ""));
                    }
                    if (pdfContentTitle.contains("{endTime}")) {
                        pdfContentTitle = pdfContentTitle.replace("{endTime}", nhVo.getEndTime().replace("-", ""));
                    }
                    PDFUtil.getCellValue(tb, pdfContentTitle, cellContentFont, null, Integer.parseInt(contentConf.getPdfContentAlign()));
                }
                document.add(tb);
            }

            log.info("添加图片logo到PDF文件中...");
            // 添加图片到PDF文件中
            PDFUtil.addImg(document, baseConf.getPdfBaseImagePath(), 50f, 50f, 460f, 710f);

            AssistPdfTableConf tableConf = new AssistPdfTableConf();
            tableConf.setBaseConfId(baseConf.getId());
            List<AssistPdfTableConf> tableList = assistPdfTableConfService.selectAssistPdfTableConfList(tableConf);
            List<AssistPdfTableConf> tableSortList = tableList.stream().sorted(Comparator.comparingInt(AssistPdfTableConf::getPdfTableSort)).collect(Collectors.toList());
            if (tableSortList != null && tableSortList.size() > 0) {
                log.info("查询配置信息，并生成PDF内容...");
                float[] width = new float[tableSortList.size()];
                for (int i = 0; i < tableSortList.size(); i++) {
                    width[i] = Float.valueOf(tableSortList.get(i).getPdfTableCellWidth());
                }
                PdfPTable table1 = new PdfPTable(width);
                table1.setSpacingBefore(4f);
                // 设置表格宽度为100%
                table1.setWidthPercentage(100.0F);
                table1.getDefaultCell().setHorizontalAlignment(1);
                // 设置表格上边框
                log.info("设置表格表头上边框信息...");
                for (int i = 0; i < tableSortList.size(); i++) {
                    PdfPCell cell = new PdfPCell(new Paragraph("", font));
                    cell.setFixedHeight(1); // 设置高度
                    cell.setHorizontalAlignment(0); // 设置对齐方式 默认水平左对齐
                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
                    cell.disableBorderSide(13); // 设置边框信息 默认只显示上下
                    table1.addCell(cell);
                }
                document.add(table1);

                PdfPTable table3 = new PdfPTable(width);
                table3.setSpacingBefore(0f);
                // 设置表格宽度为100%
                table3.setWidthPercentage(100.0F);
                table3.setHeaderRows(1);
                table3.getDefaultCell().setHorizontalAlignment(1);
                log.info("设置表格表头标题信息...");
                for (AssistPdfTableConf tc : tableSortList) {
                    PDFUtil.getCellTitleValue(table3, tc.getPdfTableTitle(), cellContentFont, Integer.parseInt(tc.getPdfTableTitleAlign()), 15);
                }
                // 设置表格表头下边框
                log.info("设置表格表头下边框信息...");
                for (int i = 0; i < tableSortList.size(); i++) {
                    PdfPCell cell = new PdfPCell(new Paragraph("", font));
                    cell.setFixedHeight(1); // 设置高度
                    cell.setHorizontalAlignment(0); // 设置对齐方式 默认水平左对齐
                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
                    cell.disableBorderSide(14); // 设置边框信息 默认只显示上下
                    table3.addCell(cell);
                }

                // 随机生成表格内容数据
                log.info("随机抓取生成数据到PDF表格中...");
                int flag = 0;
                for (String value : valueList) {
                    PDFUtil.getCellValue(table3, value, cellContentFont, Integer.parseInt(tableSortList.get(flag).getPdfTableValueBorderConf()),
                            Integer.parseInt(tableSortList.get(flag).getPdfTableValueAlign()));
                    if ((flag + 1) == tableSortList.size()) {
                        // 大小相同时，则置0
                        flag = 0;
                    } else {
                        flag++;
                    }
                }
                document.add(table3);
                // 设置下边框
                PdfPTable table2 = new PdfPTable(width);
                table2.setSpacingBefore(4f);
                // 设置表格宽度为100%
                table2.setWidthPercentage(100.0F);
                table2.getDefaultCell().setHorizontalAlignment(1);
                // 设置表格上边框
                log.info("设置表格表头上边框信息...");
                for (int i = 0; i < tableSortList.size(); i++) {
                    PdfPCell cell = new PdfPCell(new Paragraph("", font));
                    cell.setFixedHeight(1); // 设置高度
                    cell.setHorizontalAlignment(0); // 设置对齐方式 默认水平左对齐
                    cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 垂直对齐
                    cell.disableBorderSide(13); // 设置边框信息 默认只显示上下
                    table2.addCell(cell);
                }
                document.add(table2);
                // 说明
                String note = "该交易明细因不可预测的非人控技术原因可能导致数据缺失，明细内容仅供参考。";
                Font noteFont = new Font(bfChinese, 11, Font.BOLD);
                //设置内容
                Paragraph noteParagraph = new Paragraph(note, noteFont);
                //引用内容
                document.add(noteParagraph);
                log.info("PDF文件生成完成...");
            }
            //关闭文档
            document.close();
            // 信息入库操作
            if (assistPdfCreateFile.getId() == null) {
                assistPdfCreateFileService.insertAssistPdfCreateFile(assistPdfCreateFile);
            } else {
                assistPdfCreateFileService.updateAssistPdfCreateFile(assistPdfCreateFile);
            }
        } catch (DocumentException e) {
            log.error("生成PDF文件失败: {}", e.getMessage());
            log.error(e.getMessage(), e);
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
        return AjaxResult.success();
    }

    /**
     * 创建JH的PDF文件
     *
     * @param jhVo 入参
     * @return
     * @throws Exception
     */
    public AjaxResult createJhPdf(JhVo jhVo) throws Exception {
        AssistPdfCreateFile assistPdfCreateFile = null;
        if (jhVo.getCreateFileId() == null) {
            assistPdfCreateFile = new AssistPdfCreateFile();
        } else {
            assistPdfCreateFile = assistPdfCreateFileService.selectAssistPdfCreateFileById(jhVo.getCreateFileId());
        }
        // 设置值
        assistPdfCreateFile.setJhDataByReq(jhVo);
        assistPdfCreateFile.setPdfFileName();
        OutputStream outputStream = null;
        try {

            Long type = jhVo.getTypeId();
            AssistPdfBaseConf baseConf = assistPdfBaseConfService.selectAssistPdfBaseConfById(type);
            jhVo.setBaseConf(baseConf);
            jhVo.setLogoPath(baseConf.getPdfBaseImagePath());
            jhVo.setFontPath(baseConf.getPdfBaseFontPath());
            log.info("参数已处理完成，开始生成PDF文件信息...");
            assistPdfCreateFile.setPdfFilePath(baseConf.getPdfBaseSavePath());
            // String pdfFilePath = baseConf.getPdfBaseSavePath() + File.separator + "jh_create_file.pdf";
            File file = new File(assistPdfCreateFile.getPdfFilePath());
            outputStream = new FileOutputStream(file);

            // 设置PDF大小
            Document document = new Document(new RectangleReadOnly(baseConf.getPdfPaperWidth(), baseConf.getPdfPaperHeight())); // A4纸张
            //设置页边距  60:左边距，60：右边距，72：上边距，72：下边距
            document.setMargins(baseConf.getPdfPaperLeftMargin(), baseConf.getPdfPaperRightMargin(), baseConf.getPdfPaperTopMargin(), baseConf.getPdfPaperBottomMargin());
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            //打开生成的pdf文件
            document.open();
            int pageTotal = 0;

            // 获取要生成的PDF文件数据内容
            List<JhPdfDomain> list = jhVo.getSortDataList();
            // 将数据内容安装每页19行进行分组处理
            List<List<JhPdfDomain>> groupList = StringUtils.splitList(list, 19);
            // 根据数据量获取要生成的PDF总页数
            pageTotal = groupList.size();
            jhVo.setPageTotal(String.valueOf(pageTotal));
            // 将数据整理成PDF文件所需的格式
            Map<Integer, List<String>> detailMap = new HashMap<>();
            for (int h = 0; h < groupList.size(); h++) {
                List<JhPdfDomain> jhList = groupList.get(h);
                List<String> detailList = new ArrayList<>();

                StringBuilder str1 = new StringBuilder("");
                StringBuilder str2 = new StringBuilder("");
                StringBuilder str3 = new StringBuilder("");
                StringBuilder str4 = new StringBuilder("");
                StringBuilder str5 = new StringBuilder("");
                StringBuilder str6 = new StringBuilder("");
                StringBuilder str7 = new StringBuilder("");
                StringBuilder str8 = new StringBuilder("");
                StringBuilder str9 = new StringBuilder("");
                // 设置需要添加空白的数据行
                int needAddNum = 0;
                if (jhList.size() < 19) {
                    needAddNum = 19 - jhList.size();
                }

                for (int i = 0; i < jhList.size(); i++) {
                    JhPdfDomain jhDomain = jhList.get(i);
                    String note = jhDomain.getTransactionNote();
                    String oppAccount = jhDomain.getOppositionAccount();
                    str1.append(jhDomain.getSeqNo());
                    str2.append(jhDomain.getTransactionSummary());
                    str3.append(jhDomain.getTransactionCurrency());
                    str4.append(jhDomain.getTransactionBanknote());
                    str5.append(jhDomain.getTransactionDate());
                    str6.append(jhDomain.getDealAmount());
                    str7.append(jhDomain.getCurrentAmount());
                    str8.append((StringUtils.isNotBlank(note) && note.length() > 9) ? note.substring(0, 9) : note);
                    str9.append((StringUtils.isNotBlank(oppAccount) && oppAccount.length() > 22) ? oppAccount.substring(0, 22) : oppAccount);
                    if ((i < jhList.size() - 1) || needAddNum > 0) {
                        str1.append("\n\n");
                        str2.append("\n\n");
                        str3.append("\n\n");
                        str4.append("\n\n");
                        str5.append("\n\n");
                        str6.append("\n\n");
                        str7.append("\n\n");
                        str8.append("\n\n");
                        str9.append("\n\n");
                    }
                    if (needAddNum > 0) {
                        if (i == (jhList.size() - 1)) {
                            for (int m = 0; m < needAddNum; m++) {
                                str1.append(" ");
                                str2.append(" ");
                                str3.append(" ");
                                str4.append(" ");
                                str5.append(" ");
                                str6.append(" ");
                                str7.append(" ");
                                str8.append(" ");
                                str9.append(" ");
                                if (m < needAddNum - 1) {
                                    str1.append("\n\n");
                                    str2.append("\n\n");
                                    str3.append("\n\n");
                                    str4.append("\n\n");
                                    str5.append("\n\n");
                                    str6.append("\n\n");
                                    str7.append("\n\n");
                                    str8.append("\n\n");
                                    str9.append("\n\n");
                                }
                            }
                        }
                    }
                }
                detailList.add(str1.toString());
                detailList.add(str2.toString());
                detailList.add(str3.toString());
                detailList.add(str4.toString());
                detailList.add(str5.toString());
                detailList.add(str6.toString());
                detailList.add(str7.toString());
                detailList.add(str8.toString());
                detailList.add(str9.toString());
                detailMap.put(h + 1, detailList);
            }

            // 将整理好的数据塞入的实体类中
            jhVo.setDetailMap(detailMap);

            // 循环生成PDF文件
            for (int i = 0; i < pageTotal; i++) {
                jhVo.setPageNum(String.valueOf(i + 1));
                setJhPageInfo(jhVo, document);
                if (i < pageTotal - 1) {
                    document.newPage();
                }
            }
            //关闭文档
            document.close();

            // 信息入库操作
            if (assistPdfCreateFile.getId() == null) {
                assistPdfCreateFileService.insertAssistPdfCreateFile(assistPdfCreateFile);
            } else {
                assistPdfCreateFileService.updateAssistPdfCreateFile(assistPdfCreateFile);
            }
        } catch (DocumentException e) {
            log.error("生成PDF文件失败: {}", e.getMessage());
            log.error(e.getMessage(), e);
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
        return AjaxResult.success();
    }

    /**
     * 分页设置JH数据内容
     *
     * @param jhVo
     * @param document
     */
    public void setJhPageInfo(JhVo jhVo, Document document) {
        try {
            AssistPdfBaseConf baseConf = jhVo.getBaseConf();
            //创建字体
            BaseFont bf = BaseFont.createFont(baseConf.getPdfBaseFontPath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            //使用字体并给出颜色
            Font font = new Font(bf, baseConf.getPdfBaseTitleFontSize(), Integer.parseInt(baseConf.getPdfBaseTitleFontStyle()), BaseColor.BLACK);
            // 不同字体（这里定义为同一种字体：包含不同字号、不同style）
            BaseFont bfChinese = BaseFont.createFont(jhVo.getFontPath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            Font cellContentFont = new Font(bfChinese, baseConf.getPdfBaseGlobalFontSize(), Integer.parseInt(baseConf.getPdfBaseGlobalFontStyle()));

            //设置内容
            Paragraph paragraph = new Paragraph(baseConf.getPdfBaseTitle(), font);
            paragraph.setAlignment(1); // 居中显示
            //引用内容
            document.add(paragraph);

            PdfPTable descTb = new PdfPTable(Math.toIntExact(baseConf.getPdfBaseDescNum()));
            descTb.setWidthPercentage(100);

            // 查询描述内容配置信息
            log.info("查询描述文件配置信息...");
            AssistPdfContentConf contCont = new AssistPdfContentConf();
            contCont.setBaseConfId(baseConf.getId());
            List<AssistPdfContentConf> contentList = assistPdfContentConfService.selectAssistPdfContentConfList(contCont);
            List<AssistPdfContentConf> contentSortList = contentList.stream().sorted(Comparator.comparingInt(AssistPdfContentConf::getPdfContentSort)).collect(Collectors.toList());
            if (!contentSortList.isEmpty()) {
                for (AssistPdfContentConf contentConf : contentSortList) {
                    String pdfContentTitle = contentConf.getPdfContentTitle();
                    if (pdfContentTitle.contains("{userName}")) {
                        pdfContentTitle = pdfContentTitle.replace("{userName}", jhVo.getUserName());
                    }
                    if (pdfContentTitle.contains("{accountNo}")) {
                        pdfContentTitle = pdfContentTitle.replace("{accountNo}", jhVo.getAccountNo());
                    }
                    if (pdfContentTitle.contains("{startTime}")) {
                        pdfContentTitle = pdfContentTitle.replace("{startTime}", jhVo.getStartTime());
                    }
                    if (pdfContentTitle.contains("{endTime}")) {
                        pdfContentTitle = pdfContentTitle.replace("{endTime}", jhVo.getEndTime());
                    }
                    PDFUtil.getCellValue(descTb, pdfContentTitle, cellContentFont, null, Integer.parseInt(contentConf.getPdfContentAlign()));
                }
                document.add(descTb);
            }

            AssistPdfTableConf tableConf = new AssistPdfTableConf();
            tableConf.setBaseConfId(baseConf.getId());
            List<AssistPdfTableConf> tableList = assistPdfTableConfService.selectAssistPdfTableConfList(tableConf);
            List<AssistPdfTableConf> tableSortList = tableList.stream().sorted(Comparator.comparingInt(AssistPdfTableConf::getPdfTableSort)).collect(Collectors.toList());
            if (!tableSortList.isEmpty()) {
                log.info("查询配置信息，并生成PDF内容...");
                float[] width = new float[tableSortList.size()];
                for (int i = 0; i < tableSortList.size(); i++) {
                    width[i] = Float.valueOf(tableSortList.get(i).getPdfTableCellWidth());
                }
                PdfPTable columnTb = new PdfPTable(width);
                columnTb.setSpacingBefore(0f);
                // 设置表格宽度为100%
                columnTb.setWidthPercentage(100.0F);
                columnTb.getDefaultCell().setHorizontalAlignment(1);
                log.info("设置表格表头标题信息...");
                for (AssistPdfTableConf tc : tableSortList) {
                    PDFUtil.getCellTitleValue(columnTb, tc.getPdfTableTitle(), cellContentFont, Integer.parseInt(tc.getPdfTableTitleAlign()), Integer.valueOf(tc.getPdfTableBorderConf()));
                }
                log.info("设置数据表格信息...");
                Map<Integer, List<String>> detailMap = jhVo.getDetailMap();
                List<String> strings = detailMap.get(Integer.valueOf(jhVo.getPageNum()));
                for (int i = 0; i < tableSortList.size(); i++) {
                    AssistPdfTableConf tb = tableSortList.get(i);
                    PDFUtil.getCellValue(columnTb, strings.get(i), cellContentFont, Integer.valueOf(tb.getPdfTableValueBorderConf()), Integer.parseInt(tb.getPdfTableValueAlign()));
                }
                document.add(columnTb);
            }

            // 配置页码信息
            PdfPTable pageTb = new PdfPTable(Math.toIntExact(4));
            pageTb.setWidthPercentage(100);
            PDFUtil.getCellValue(pageTb, "生成时间:" + jhVo.getCreateTime(), cellContentFont, null, 0);
            PDFUtil.getCellValue(pageTb, "", cellContentFont, null, 0);
            PDFUtil.getCellValue(pageTb, "当前页：" + jhVo.getPageNum(), cellContentFont, null, 0);
            PDFUtil.getCellValue(pageTb, "总页数：" + jhVo.getPageTotal(), cellContentFont, null, 0);
            document.add(pageTb);
            log.info("添加图片logo到PDF文件中...");
            // 添加图片到PDF文件中
            PDFUtil.addImg(document, jhVo.getLogoPath(), 105f, 105f, 70f, 100f);
            log.info("PDF文件生成完成...");
        } catch (Exception e) {
            log.error("出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 创建Wx的PDF文件
     *
     * @param wxVo 入参
     * @return
     * @throws Exception
     */
    public AjaxResult createWxPdf(WxVo wxVo) throws Exception {
        AssistPdfCreateFile assistPdfCreateFile = null;
        if (wxVo.getCreateFileId() == null) {
            assistPdfCreateFile = new AssistPdfCreateFile();
        } else {
            assistPdfCreateFile = assistPdfCreateFileService.selectAssistPdfCreateFileById(wxVo.getCreateFileId());
        }
        // 设置值
        assistPdfCreateFile.setPdfFileName();
        assistPdfCreateFile.setWxDataByReq(wxVo);

        log.info("设置每一行每一列的值...");
        List<String> valueList = new ArrayList<>();
        List<WxPdfDomain> sortedDataList = wxVo.getSortDataList();
        for (WxPdfDomain domain : sortedDataList) {
            DateTime date = DateUtil.parse(domain.getTransactionDate() + domain.getTransactionTime());
            String dateStr = DateUtil.format(date, "yyyy-MM-dd hh:mm:ss");
            valueList.add(domain.getTransactionSummary());
            valueList.add(dateStr);
            valueList.add(domain.getTransactionChannels());
            valueList.add(domain.getLogNo());
            valueList.add(domain.getCurrentBalance());
            valueList.add(domain.getTransactionMoneyInt() + domain.getAfterNum());
            valueList.add(domain.getOppositionInformation());
            valueList.add(domain.getTransactionNote());
        }

        // 生成的PDF文件地址
        log.info("参数以处理完成，开始生成PDF文件信息...");
        OutputStream outputStream = null;
        try {
            // 定义全局的字体静态变量
            BaseFont bf;
            Font font = null;
            Font cellContentFont = null;
            AssistPdfBaseConf baseConf = assistPdfBaseConfService.selectAssistPdfBaseConfById(wxVo.getTypeId());
            String pdfBaseSavePath = baseConf.getPdfBaseSavePath();

            assistPdfCreateFile.setPdfFilePath(pdfBaseSavePath);

            File file = new File(assistPdfCreateFile.getPdfFilePath());
            outputStream = new FileOutputStream(file);

            String fontPath = baseConf.getPdfBaseFontPath();
            // 最大宽度
            //创建字体
            bf = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            //使用字体并给出颜色
            font = new Font(bf, baseConf.getPdfBaseTitleFontSize(), Integer.valueOf(baseConf.getPdfBaseTitleFontStyle()), BaseColor.BLACK);
            // 不同字体（这里定义为同一种字体：包含不同字号、不同style）
            BaseFont bfChinese = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            cellContentFont = new Font(bfChinese, baseConf.getPdfBaseGlobalFontSize(), Integer.valueOf(baseConf.getPdfBaseGlobalFontStyle()));

            // 设置PDF大小
            Document document = new Document(new RectangleReadOnly(Float.valueOf(baseConf.getPdfPaperWidth()), Float.valueOf(baseConf.getPdfPaperHeight()))); // A4纸张
            //设置页边距  60:左边距，60：右边距，72：上边距，72：下边距
            document.setMargins(baseConf.getPdfPaperLeftMargin(), baseConf.getPdfPaperRightMargin(), baseConf.getPdfPaperTopMargin(), baseConf.getPdfPaperBottomMargin());
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            //添加页码
            // writer.setPageEvent(new PdfPageUtil());
            //打开生成的pdf文件
            document.open();
            //设置内容
            //设置内容
            Paragraph nullParagraph = new Paragraph("\t", cellContentFont);
            document.add(nullParagraph);
            Paragraph codeParagraph = new Paragraph("编号：" + wxVo.getCode(), cellContentFont);
            codeParagraph.setAlignment(0); // 居中显示
            codeParagraph.setSpacingBefore(33f);
            codeParagraph.setSpacingAfter(23f);
            //引用内容
            document.add(codeParagraph);

            //设置内容
            Paragraph paragraph = new Paragraph(baseConf.getPdfBaseTitle(), font);
            paragraph.setAlignment(Integer.valueOf(baseConf.getPdfBaseTitleAlign())); // 居中显示
            paragraph.setSpacingAfter(9f);
            //引用内容
            document.add(paragraph);

            PdfPTable tb = new PdfPTable(Math.toIntExact(baseConf.getPdfBaseDescNum()));
            tb.setWidthPercentage(100);

            // 查询描述内容配置信息
            log.info("查询描述文件配置信息...");
            AssistPdfContentConf contCont = new AssistPdfContentConf();
            contCont.setBaseConfId(baseConf.getId());
            List<AssistPdfContentConf> contentList = assistPdfContentConfService.selectAssistPdfContentConfList(contCont);
            List<AssistPdfContentConf> contentSortList = contentList.stream().sorted(Comparator.comparingInt(AssistPdfContentConf::getPdfContentSort)).collect(Collectors.toList());
            float[] widthContent = new float[contentSortList.size()];
            if (!contentSortList.isEmpty()) {
                int i = 0;
                for (AssistPdfContentConf contentConf : contentSortList) {
                    widthContent[i] = Float.valueOf(contentConf.getRemark());
                    String pdfContentTitle = contentConf.getPdfContentTitle();
                    if (StringUtils.contains(pdfContentTitle, "%s")) {
                        pdfContentTitle = String.format(pdfContentTitle, wxVo.getUserName(), wxVo.getIdCode(), wxVo.getWxCode());
                    }
                    PDFUtil.getCellValue(tb, pdfContentTitle, cellContentFont, null, Integer.parseInt(contentConf.getPdfContentAlign()));
                    i++;
                }
                document.add(tb);
            }

            PdfPTable table1 = new PdfPTable(widthContent);
            table1.setSpacingBefore(0f);
            // 设置表格宽度为100%
            table1.setWidthPercentage(100.0F);
            // table3.setHeaderRows(1);
            table1.getDefaultCell().setHorizontalAlignment(1);
            log.info("设置表格表头标题信息...");
            PDFUtil.getCellTitleValue(table1, "交易明细对应时间段", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table1, String.format("%s 00:00:00至%s 23:59:59", wxVo.getStartTime(), wxVo.getEndTime()), cellContentFont, 1, 0);
            document.add(table1);

            PdfPTable table2 = new PdfPTable(1);
            float[] columnWidths2 = {100f};
            table2.setTotalWidth(columnWidths2);
            table2.setSpacingBefore(0f);
            // 设置表格宽度为100%
            table2.setWidthPercentage(100.0F);
            // table3.setHeaderRows(1);
            table2.getDefaultCell().setHorizontalAlignment(1);
            log.info("设置表格表头标题信息...");
            PDFUtil.getCellTitleValue(table2, "具体交易明细", cellContentFont, 1, 0);
            document.add(table2);


            AssistPdfTableConf tableConf = new AssistPdfTableConf();
            tableConf.setBaseConfId(baseConf.getId());
            List<AssistPdfTableConf> tableList = assistPdfTableConfService.selectAssistPdfTableConfList(tableConf);
            List<AssistPdfTableConf> tableSortList = tableList.stream().sorted(Comparator.comparingInt(AssistPdfTableConf::getPdfTableSort)).collect(Collectors.toList());
            if (!tableSortList.isEmpty()) {
                log.info("查询配置信息，并生成PDF内容...");
                float[] width = new float[tableSortList.size()];
                for (int i = 0; i < tableSortList.size(); i++) {
                    width[i] = Float.valueOf(tableSortList.get(i).getPdfTableCellWidth());
                }
                PdfPTable table3 = new PdfPTable(width);
                table3.setSpacingBefore(4f);
                // 设置表格宽度为100%
                table3.setWidthPercentage(100.0F);
                table3.getDefaultCell().setHorizontalAlignment(1);
                log.info("设置表格表头标题信息...");
                for (AssistPdfTableConf t : tableSortList) {
                    PDFUtil.getCellTitleValue(table3, t.getPdfTableTitle(), cellContentFont, Integer.valueOf(t.getPdfTableTitleAlign()), Integer.valueOf(t.getPdfTableBorderConf()));
                }

                // 随机生成表格内容数据
                if (!valueList.isEmpty()) {
                    log.info("添加图片logo到PDF文件的第一页中...");
                    // 添加图片logo到PDF文件的第一页中
                    PDFUtil.addImg(document, baseConf.getPdfBaseImagePath(), 120f, 120f, 440f, 75f);
                    int flag = 0;
                    log.info("将生成数据到PDF表格中...");
                    for (String value : valueList) {
                        PDFUtil.getCellValue(table3, value, cellContentFont, Integer.parseInt(tableSortList.get(flag).getPdfTableValueBorderConf()),
                                Integer.parseInt(tableSortList.get(flag).getPdfTableValueAlign()));
                        if ((flag + 1) == tableSortList.size()) {
                            // 大小相同时，则置0
                            flag = 0;
                        } else {
                            flag++;
                        }
                    }
                }
                document.add(table3);

                //设置底部内容
                String footContent = "说明：\n" +
                        "1.本《微信支付交易明细证明》仅证明：在用户选择的时间段内，用户通过微信支付账户发生的历史交易记录情况，包括零钱，零钱通，银行卡快捷支付等，其中，零钱还包括用户在账户升级服务期间通过零钱账户发生的交易。\n" +
                        "2.本《微信支付交易明细证明》仅用于用户申请本证明时注明的用途，不得用于其他用途，并且不得修改或涂改。\n" +
                        "3.对于红包，转账，二维码收付款交易，交易对方显示为本文件生成当时该用户对交易对方的微信备注或者交易对方的昵称，仅供参考。\n" +
                        "4.零钱的充值和提现，零钱通的存入和取出，信用卡还款，购买理财通等用户内部资金交易，不计入收入或支出，记为其他类。\n" +
                        "5.如《微信支付交易明细证明》与用户在财付通系统中的账户记录不一致的，以系统中的账户记录为准。";
                Paragraph footParagraph = new Paragraph(footContent, cellContentFont);
                footParagraph.setAlignment(0); // 居中显示
                //引用内容
                document.add(footParagraph);
                String footContent1 = "财付通支付科技有限公司";
                Paragraph footParagraph1 = new Paragraph(footContent1, cellContentFont);
                footParagraph1.setAlignment(2); // 居中显示
                //引用内容
                document.add(footParagraph1);
                String footContent2 = "盖章";
                Paragraph footParagraph2 = new Paragraph(footContent2, cellContentFont);
                footParagraph2.setAlignment(2); // 居中显示
                //引用内容
                document.add(footParagraph2);

                log.info("添加图片logo到PDF文件中...");
                // 添加图片到PDF文件中
                PDFUtil.addImg(document, baseConf.getPdfBaseImagePath(), 120f, 120f, 440f, 75f);
                log.info("PDF文件生成完成...");

            }
            //关闭文档
            document.close();
            // 信息入库操作
            if (assistPdfCreateFile.getId() == null) {
                assistPdfCreateFileService.insertAssistPdfCreateFile(assistPdfCreateFile);
            } else {
                assistPdfCreateFileService.updateAssistPdfCreateFile(assistPdfCreateFile);
            }
        } catch (DocumentException e) {
            log.error("生成PDF文件失败: {}", e.getMessage());
            log.error(e.getMessage(), e);
        } finally {
            if (outputStream != null) {
                outputStream.close();
            }
        }
        return AjaxResult.success();
    }


    /**
     * 根据反射获取属性值
     *
     * @param list
     * @return
     */
    private List<String> getFieldValue(List<TableValue> list) {
        List<String> valueList = new ArrayList<>();
        try {
            if (list != null && list.size() > 0) {
                for (TableValue tableValue : list) {
                    Class<? extends TableValue> tableValueClazz = tableValue.getClass();
                    Field[] fields = tableValueClazz.getDeclaredFields();
                    for (Field field : fields) {
                        field.setAccessible(true);
                        String name = field.getName();
                        if (StringUtils.equalsAny(name, "transactionMoneyInt", "sortNo")) {
                            continue;
                        }
                        String value = String.valueOf(field.get(tableValue));
                        // log.info("{}：{}", name, value);
                        valueList.add(value);
                    }
                }
            }
        } catch (IllegalAccessException e) {
            log.error("反射获取属性值异常:{}", e.getMessage());
            log.error(e.getMessage(), e);
        }
        return valueList;
    }

    public static void main(String[] args) {
        // 生成的PDF文件地址
        try {
            log.info("参数以处理完成，开始生成PDF文件信息...");
            String pdfBaseSavePath = "E:\\GCH\\inOutDetail\\download";
            String pdfFilePath = pdfBaseSavePath + "\\wx_create_file.pdf";
            File file = new File(pdfFilePath);
            OutputStream outputStream = new FileOutputStream(file);

            // 设置PDF大小
            Document document = new Document(new RectangleReadOnly(595, 842)); // A4纸张
            //设置页边距  60:左边距，60：右边距，72：上边距，72：下边距
            document.setMargins(40, 40, 40, 30);
            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            //打开生成的pdf文件
            document.open();
            int pageTotal = 3;

            // 编号
            String code = "202405291560114891452787691182105129172";
            // 用户名
            String userName = "李瑞霞";
            // 身份证号
            String idCode = "410126197504272120";
            // 微信号
            String wxCode = "wxid_6hj96ov9325x22";
            String startTime = "2023-11-29 00:00:00";
            String endTime = "2024-05-29 15:44:51";
            String fontPath = "C:\\Windows\\Fonts\\simkai.ttf";
            String logoPath = "E:\\GCH\\inOutDetail\\download\\wx_logo.png";
            String descStr = String.format("兹证明：%s(居民身份证：%s)，在其微信号：%s中的交易明细信息如下：", userName, idCode, wxCode);
            String descStr1 = "币种：人民币/单位：元";


            //创建字体
            BaseFont bf = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            //使用字体并给出颜色
            Font font = new Font(bf, 16, 0, BaseColor.BLACK);
            // 不同字体（这里定义为同一种字体：包含不同字号、不同style）
            BaseFont bfChinese = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            Font cellContentFont = new Font(bfChinese, 11, 0);

            //设置内容
            Paragraph codeParagraph = new Paragraph("编号：" + code, cellContentFont);
            codeParagraph.setAlignment(0); // 居中显示
            //引用内容
            document.add(codeParagraph);

            //设置内容
            Paragraph paragraph = new Paragraph("微信支付交易明细证明", font);
            paragraph.setAlignment(1); // 居中显示
            //引用内容
            document.add(paragraph);

            PdfPTable tb = new PdfPTable(Math.toIntExact(1));
            tb.setWidthPercentage(100);

            // 查询描述内容配置信息
            log.info("查询描述文件配置信息...");
            PDFUtil.getCellValue(tb, descStr, cellContentFont, null, 0);
            PDFUtil.getCellValue(tb, descStr1, cellContentFont, null, 2);
            document.add(tb);

            PdfPTable table1 = new PdfPTable(2);
            float[] columnWidths = {23.3f, 76.7f};
            table1.setTotalWidth(columnWidths);
            table1.setSpacingBefore(0f);
            // 设置表格宽度为100%
            table1.setWidthPercentage(100.0F);
            // table3.setHeaderRows(1);
            table1.getDefaultCell().setHorizontalAlignment(1);
            log.info("设置表格表头标题信息...");
            PDFUtil.getCellTitleValue(table1, "交易明细对应时间段", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table1, startTime + "至" + endTime, cellContentFont, 1, 0);
            document.add(table1);

            PdfPTable table2 = new PdfPTable(1);
            float[] columnWidths2 = {100f};
            table2.setTotalWidth(columnWidths2);
            table2.setSpacingBefore(0f);
            // 设置表格宽度为100%
            table2.setWidthPercentage(100.0F);
            // table3.setHeaderRows(1);
            table2.getDefaultCell().setHorizontalAlignment(1);
            log.info("设置表格表头标题信息...");
            PDFUtil.getCellTitleValue(table2, "具体交易明细", cellContentFont, 1, 0);
            document.add(table2);

            PdfPTable table3 = new PdfPTable(8);
            float[] columnWidths3 = {23.3f, 9.7f, 9.7f, 11.7f, 9.7f, 9.7f, 9.7f, 16.5f};
            table3.setTotalWidth(columnWidths3);
            table3.setSpacingBefore(0f);
            // 设置表格宽度为100%
            table3.setWidthPercentage(100.0F);
            // table3.setHeaderRows(1);
            table3.getDefaultCell().setHorizontalAlignment(1);
            log.info("设置表格表头标题信息...");
            PDFUtil.getCellTitleValue(table3, "交易单号", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "交易时间", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "交易类型", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "收/支/其他", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "交易方式", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "金额(元)", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "交易对方", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "商户单号", cellContentFont, 1, 0);
            document.add(table3);
            // 具体数据处理


            //设置底部内容
            String footContent = "说明：\n" +
                    "1.本《微信支付交易明细证明》仅证明：在用户选择的时间段内，用户通过微信支付账户发生的历史交易记录情况，包括零钱，零钱通，银行卡快捷支付等，其中，零钱还包括用户在账户升级服务期间通过零钱账户发生的交易。\n" +
                    "2.本《微信支付交易明细证明》仅用于用户申请本证明时注明的用途，不得用于其他用途，并且不得修改或涂改。\n" +
                    "3.对于红包，转账，二维码收付款交易，交易对方显示为本文件生成当时该用户对交易对方的微信备注或者交易对方的昵称，仅供参考。\n" +
                    "4.零钱的充值和提现，零钱通的存入和取出，信用卡还款，购买理财通等用户内部资金交易，不计入收入或支出，记为其他类。\n" +
                    "5.如《微信支付交易明细证明》与用户在财付通系统中的账户记录不一致的，以系统中的账户记录为准。";
            Paragraph footParagraph = new Paragraph(footContent, cellContentFont);
            footParagraph.setAlignment(0); // 居中显示
            //引用内容
            document.add(footParagraph);
            String footContent1 = "财付通支付科技有限公司";
            Paragraph footParagraph1 = new Paragraph(footContent1, cellContentFont);
            footParagraph1.setAlignment(2); // 居中显示
            //引用内容
            document.add(footParagraph1);
            String footContent2 = "盖章";
            Paragraph footParagraph2 = new Paragraph(footContent2, cellContentFont);
            footParagraph2.setAlignment(2); // 居中显示
            //引用内容
            document.add(footParagraph2);

            log.info("添加图片logo到PDF文件中...");
            // 添加图片到PDF文件中
            PDFUtil.addImg(document, logoPath, 120f, 120f, 440f, 75f);
            log.info("PDF文件生成完成...");

            //关闭文档
            document.close();
        } catch (Exception e) {
            log.error("生成PDF文件失败: {}", e.getMessage());
            log.error(e.getMessage(), e);
        } finally {
            /*if (outputStream != null) {
                // outputStream.close();
            }*/
        }
    }

    public static void setPageInfo(JhVo jhVo, Document document) {
        try {
            //创建字体
            BaseFont bf = BaseFont.createFont(jhVo.getFontPath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            //使用字体并给出颜色
            Font font = new Font(bf, 16, 0, BaseColor.BLACK);
            // 不同字体（这里定义为同一种字体：包含不同字号、不同style）
            BaseFont bfChinese = BaseFont.createFont(jhVo.getFontPath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            Font cellContentFont = new Font(bfChinese, 11, 0);

            //设置内容
            Paragraph paragraph = new Paragraph("中国建设银行个人活期账户全部交易明细\n\n", font);
            paragraph.setAlignment(1); // 居中显示
            //引用内容
            document.add(paragraph);

            PdfPTable tb = new PdfPTable(Math.toIntExact(4));
            tb.setWidthPercentage(100);

            // 查询描述内容配置信息
            log.info("查询描述文件配置信息...");
            PDFUtil.getCellValue(tb, "卡号/账号:" + jhVo.getAccountNo(), cellContentFont, null, 0);
            PDFUtil.getCellValue(tb, "客户名称:燃源晨", cellContentFont, null, 0);
            PDFUtil.getCellValue(tb, "起始日期:20230217", cellContentFont, null, 0);
            PDFUtil.getCellValue(tb, "结束日期:20240217", cellContentFont, null, 0);
            document.add(tb);

            PdfPTable table3 = new PdfPTable(9);
            float[] columnWidths = {4.4f, 13f, 7.3f, 5.2f, 8f, 9.5f, 9.5f, 18f, 25f};
            table3.setTotalWidth(columnWidths);
            table3.setSpacingBefore(0f);
            // 设置表格宽度为100%
            table3.setWidthPercentage(100.0F);
            // table3.setHeaderRows(1);
            table3.getDefaultCell().setHorizontalAlignment(1);
            log.info("设置表格表头标题信息...");
            PDFUtil.getCellTitleValue(table3, "序号", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "摘要", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "币种", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "钞汇", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "交易日期", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "交易金额", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "账户余额", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "交易地点/附言", cellContentFont, 1, 0);
            PDFUtil.getCellTitleValue(table3, "对方账号与户名", cellContentFont, 1, 0);

            // String content = "1\n\n2\n\n3\n\n4\n\n5\n\n6\n\n7\n\n8\n\n9\n\n10\n\n11\n\n12\n\n13\n\n14\n\n15\n\n16\n\n17\n\n18\n\n19";
            Map<Integer, List<String>> detailMap = jhVo.getDetailMap();
            List<String> strings = detailMap.get(Integer.valueOf(jhVo.getPageNum()));
            for (int i = 0; i < 9; i++) {
                PDFUtil.getCellValue(table3, strings.get(i), cellContentFont, 1, 0);
            }
            document.add(table3);

            // 配置页码信息
            PdfPTable pageTb = new PdfPTable(Math.toIntExact(4));
            pageTb.setWidthPercentage(100);
            PDFUtil.getCellValue(pageTb, "生成时间:" + jhVo.getCreateTime(), cellContentFont, null, 0);
            PDFUtil.getCellValue(pageTb, "", cellContentFont, null, 0);
            PDFUtil.getCellValue(pageTb, "当前页：" + jhVo.getPageNum(), cellContentFont, null, 0);
            PDFUtil.getCellValue(pageTb, "总页数：" + jhVo.getPageTotal(), cellContentFont, null, 0);
            document.add(pageTb);
            log.info("添加图片logo到PDF文件中...");
            // 添加图片到PDF文件中
            PDFUtil.addImg(document, jhVo.getLogoPath(), 105f, 105f, 70f, 100f);
            log.info("PDF文件生成完成...");
        } catch (Exception e) {
            log.error("出现异常：{}", e.getMessage());
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }


}
